/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cloudbus.cloudsim.power.models.scheduling.client;

import java.util.ArrayList;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.CloudletSchedulerDynamicWorkload;
import org.cloudbus.cloudsim.UtilizationModelStochastic;
import org.cloudbus.cloudsim.Vm;

/**
 *
 * @author Márcio Costa Junior - University of São Paulo, Montana State University
 * 
 * Represents a request to be sent to the cloud
 */
public class Request {
    
    //Jobs to run
    private ArrayList<Job> jobs;
    
    //Time frame reserved to this request
    private long timeFrame;
    
    //Middleware that the request has to be sent to
    private int brokerId;
    
    //Service required
    private int service;
    
    private int start;
    
    private int end;
    
    public static int LESS_NETWORK_DELAY = 0;
    
    public static int LESS_ENERGY_COSTS = 1;
    
    private int preference;
    
    private int clientId;
    
    public Request(long timeFrame, int brokerId){
        setTimeFrame(timeFrame);
        setJobs(new ArrayList<Job>());
        setBrokerId(brokerId);
        setService(0);
        setPreference(Request.LESS_ENERGY_COSTS);
    }
    
    //Generates a certain jobs number based on some distribution
    public void generateJobsDristribution(){
        
        //Uniform distribution...All the vms and apps with the same features 
        int mips[] = {500};
        //Vms' features
        int pesNumber = 1;
        int ram = 128;
        long bw = 2500;
        long size = 2500;
        String vmm = "Xen";
        
        //Cloudlets' features
        long length = 150000;
        long fileSize = 300;
        long outputSize = 300;
        
        setJobs(new ArrayList<Job>());
        
        //Adding jobs to the main list
        for(int i = start; i < end; i++){
            Vm vm = createVms(i, mips, pesNumber, ram, bw, size, vmm);
            Cloudlet cloudlet = createCloulets(i, length, pesNumber, fileSize, outputSize);
            jobs.add(new Job(vm, cloudlet));
        }
   
    }
    
    private Vm createVms(int index, int mips[], int pesNumber, 
            int ram, long bw, long size, String vmm){
                        
			Vm vm = new Vm(index, getBrokerId(), mips[index % mips.length], pesNumber, ram, bw, size, 
                                vmm, new CloudletSchedulerDynamicWorkload(mips[index % mips.length], pesNumber));
                        return vm;
    }
    
    private Cloudlet createCloulets(int index, long length, int pesNumber, 
            long fileSize, long outputSize){

			Cloudlet cloudlet = new Cloudlet(index, length, pesNumber, fileSize, outputSize, 
                                new UtilizationModelStochastic(), new UtilizationModelStochastic(), 
                                new UtilizationModelStochastic());
			cloudlet.setUserId(getBrokerId());
			cloudlet.setVmId(index);
                        
                        return cloudlet;
		
    }

    /**
     * @return the jobs
     */
    public ArrayList<Job> getJobs() {
        return jobs;
    }

    /**
     * @param jobs the jobs to set
     */
    public void setJobs(ArrayList<Job> jobs) {
        this.jobs = jobs;
    }

    /**
     * @return the timeFrame
     */
    public long getTimeFrame() {
        return timeFrame;
    }

    /**
     * @param timeFrame the timeFrame to set
     */
    public void setTimeFrame(long timeFrame) {
        this.timeFrame = timeFrame;
    }

    /**
     * @return the brokerId
     */
    public int getBrokerId() {
        return brokerId;
    }

    /**
     * @param brokerId the brokerId to set
     */
    public void setBrokerId(int brokerId) {
        this.brokerId = brokerId;
    }

    /**
     * @return the service
     */
    public int getService() {
        return service;
    }

    /**
     * @param service the service to set
     */
    public void setService(int service) {
        this.service = service;
    }

    /**
     * @return the start
     */
    public int getStart() {
        return start;
    }

    /**
     * @param start the start to set
     */
    public void setStart(int start) {
        this.start = start;
    }

    /**
     * @return the end
     */
    public int getEnd() {
        return end;
    }

    /**
     * @param end the end to set
     */
    public void setEnd(int end) {
        this.end = end;
    }

    /**
     * @return the preference
     */
    public int getPreference() {
        return preference;
    }

    /**
     * @param preference the preference to set
     */
    public void setPreference(int preference) {
        this.preference = preference;
    }

    /**
     * @return the clientId
     */
    public int getClientId() {
        return clientId;
    }

    /**
     * @param clientId the clientId to set
     */
    public void setClientId(int clientId) {
        this.clientId = clientId;
    }
    
}
